#include "BlockQueue.hpp"
#include "Thread.hpp"
#include <vector>
#include <unistd.h>
#include"Task.hpp"
#include<ctime>

using namespace ThreadModule;
using blockqueue_t = BlockQueue<Task>;

void Consumer(blockqueue_t &bq)
{
    while (1)
    {
        int data = 0;
        sleep(1);
        // 从队列获取任务
        Task t;
        bq.Pop(&t);
        std::cout<<"Consumer cal result is: " << t.Execute() << std::endl;
        // std::cout << bq << std::endl;
        // 处理任务
    }
}
void Productor(blockqueue_t &bq)
{   
    
    srand(time(nullptr)^pthread_self());
    while (1)
    {

        
        // 产生任务并入队列
        int a = rand()%10+2;
        int b = rand()%20+5;
        Task t(a,b);
        std::cout<<"Product a, b is "<< a <<" "<< b <<std::endl;
        bq.Enqueue(t);
        
    }
}
void StartCommon(std::vector<Thread<blockqueue_t >> *threads, int num, blockqueue_t &bq, func_t<blockqueue_t > func)
{
    int a = 10;
    for (int i = 0; i < num; i++)
    {
        std::string name = "thread-" + std::to_string(i + 1);
        threads->emplace_back(func, bq, name);
        threads->back().Start();
    }
}

void Startconsumer(std::vector<Thread<blockqueue_t >> *threads, int num, blockqueue_t &bq)
{
    StartCommon(threads,num,bq,Consumer);
}

void Startproductor(std::vector<Thread<blockqueue_t>> *threads, int num, blockqueue_t &bq)
{
    StartCommon(threads,num,bq,Productor);
}   

void WaitAllThread(std::vector<Thread<blockqueue_t >> &threads)
{
    for (auto &thread : threads)
    {
        thread.Join();
    }
}

int main()
{
    blockqueue_t *bq = new blockqueue_t(5);
    std::vector<Thread<blockqueue_t>> threads;
    Startconsumer(&threads, 3, *bq);
    Startproductor(&threads, 1, *bq);
    WaitAllThread(threads);
}